package cn.itcast.nems.studentrecord.service.impl;

import cn.itcast.nems.common.account.AccountHolder;
import cn.itcast.nems.oldems.dao.entiry.Student;
import cn.itcast.nems.oldems.dao.mapper.StudentMapper;
import cn.itcast.nems.studentrecord.dao.dataobject.ClassInfoDO;
import cn.itcast.nems.studentrecord.dao.entity.StudentRecordStudentRelationship;
import cn.itcast.nems.studentrecord.dao.mapper.StudentRecordMapper;
import cn.itcast.nems.studentrecord.dao.mapper.StudentRecordStudentRelationshipMapper;
import cn.itcast.nems.studentrecord.dto.odto.EmsClassDTO;
import cn.itcast.nems.studentrecord.dto.odto.StudentAndClassInfoDTO;
import cn.itcast.nems.studentrecord.dto.odto.StudentBasicDTO;
import cn.itcast.nems.studentrecord.service.studentrecord.StudentRecordOService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Service
@RequiredArgsConstructor
public class StudentRecordOServiceImpl implements StudentRecordOService {

    private final StudentMapper studentMapper;
    private final StudentRecordMapper studentRecordMapper;
    private final StudentRecordStudentRelationshipMapper studentRecordStudentRelationshipMapper;

    @Override
    public StudentBasicDTO getStudentBasic(String accountId) {
        Student student = studentMapper.selectOne(
                new QueryWrapper<Student>()
                        .lambda()
                        .eq(Student::getAccountId, accountId)
        );
        if (student == null) return null;
        StudentBasicDTO dto = new StudentBasicDTO();
        dto.setId(student.getId());
        dto.setAccountId(student.getAccountId());
        dto.setName(student.getName());
        dto.setNumber(student.getNumber());
        dto.setPhone(student.getPhone());
        dto.setIdCard(student.getIdcard());
        return dto;
    }

    @Override
    public List<EmsClassDTO> queryStudentClasses(
            String accountID, Boolean pending, Boolean deleted, Boolean graduation
    ) {
        Assert.hasText(accountID, "缺少账号信息");
        final List<ClassInfoDO> classInfos = this.studentRecordMapper.getClassInfos(
                accountID,
                pending,
                deleted,
                graduation
        );
        List<EmsClassDTO> classInfoDTOS = new ArrayList<>();
        if (classInfos != null && !classInfos.isEmpty()) {
            classInfos.forEach(ci -> {
                EmsClassDTO dto = new ObjectMapper()
                        .configure(JsonGenerator.Feature.IGNORE_UNKNOWN, Boolean.TRUE)
                        .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, Boolean.FALSE)
                        .convertValue(ci, EmsClassDTO.class);
                dto.setValid(true);
                classInfoDTOS.add(dto);
            });
        }
        return classInfoDTOS;
    }

    @Override
    public List<EmsClassDTO> findTeacherInnerClasses(String email, Boolean pending) {
        Assert.hasText(email, "缺少邮箱信息");
        final List<ClassInfoDO> classInfos = this.studentRecordMapper.getClassInfosTeacher(
                email,
                pending,
                false,
                false
        );
        List<EmsClassDTO> classInfoDTOS = new ArrayList<>();
        if (classInfos != null && !classInfos.isEmpty()) {
            classInfos.forEach(ci -> {
                EmsClassDTO dto = new ObjectMapper()
                        .configure(JsonGenerator.Feature.IGNORE_UNKNOWN, Boolean.TRUE)
                        .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, Boolean.FALSE)
                        .convertValue(ci, EmsClassDTO.class);
                dto.setValid(true);
                classInfoDTOS.add(dto);
            });
        }
        return classInfoDTOS;
    }

    @Override
    public StudentAndClassInfoDTO moreInfo(String accountId, boolean includePending, boolean includeDeleted, boolean isGraduation) {
        StudentAndClassInfoDTO result = new StudentAndClassInfoDTO();
        result.setStudentBasicDTO(this.getStudentBasic(accountId));
        result.setClassDTOList(Collections.emptyList());
        return result;
    }

    @Override
    public Boolean studentRecordMergedCallBack(Integer fromStudentId, Integer toStudentId, String employee) {
        studentRecordStudentRelationshipMapper.update(
                null,
                new UpdateWrapper<StudentRecordStudentRelationship>(null)
                        .lambda()
                        .eq(StudentRecordStudentRelationship::getStudentId, fromStudentId)
                        .set(StudentRecordStudentRelationship::getStudentId, toStudentId)
                        .set(StudentRecordStudentRelationship::getModifiedBy, employee)
                        .set(StudentRecordStudentRelationship::getModifiedDatetime, LocalDateTime.now())
        );
        return Boolean.TRUE;
    }
}
